package com.cq.hd.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cq.hd.common.enums.biz.BusinessGroupDefaultStateEnum;
import com.cq.hd.common.exception.BusinessException;
import com.cq.hd.common.pagination.Page;
import com.cq.hd.common.response.Throw;
import com.cq.hd.member.api.dto.BusinessGroupPageDto;
import com.cq.hd.member.api.dto.BusinessGroupSaveDto;
import com.cq.hd.member.api.vo.BusinessGroupPageVo;
import com.cq.hd.member.mapper.TbBusinessAgentMapper;
import com.cq.hd.member.mapper.TbBusinessMapper;
import com.cq.hd.member.po.TbBusinessAgentPo;
import com.cq.hd.member.po.TbBusinessGroupPo;
import com.cq.hd.member.mapper.TbBusinessGroupMapper;
import com.cq.hd.member.service.TbBusinessGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商家经纪人分组表 服务实现类
 * </p>
 *
 * @author mYunYu
 * @since 2023-12-07
 */
@Service
public class TbBusinessGroupServiceImpl extends ServiceImpl<TbBusinessGroupMapper, TbBusinessGroupPo> implements TbBusinessGroupService {

    @Autowired
    private TbBusinessMapper businessMapper;

    @Autowired
    private TbBusinessAgentMapper businessAgentMapper;

    // 商家、经纪人分组下拉列表
    @Override
    public List<BusinessGroupPageVo> selectList(BusinessGroupPageDto businessGroupPageDto) {
        return baseMapper.lisBusinessGroupByDto(businessGroupPageDto);
    }

    // 商家、经纪人分组列表
    @Override
    public Page<BusinessGroupPageVo> pageBusinessGroup(BusinessGroupPageDto businessGroupPageDto) {
        PageHelper.startPage(businessGroupPageDto.getPageNum(), businessGroupPageDto.getPageSize());
        log.error("are you ok" + businessGroupPageDto);
        List<BusinessGroupPageVo> businessGroupPageVos = baseMapper.lisBusinessGroupByDto(businessGroupPageDto);
        if (!CollectionUtils.isEmpty(businessGroupPageVos)) {
            List<Long> groupId = businessGroupPageVos.stream().map(BusinessGroupPageVo::getId).collect(Collectors.toList());

            Map<Long, List<TbBusinessAgentPo>> businessAgentMap = new HashMap<>();
            List<TbBusinessAgentPo> tbBusinessAgentPos = businessAgentMapper.selectList(new QueryWrapper<TbBusinessAgentPo>()
                    .eq("del_state", 0)
                    .in("group_id", groupId));
            if (!CollectionUtils.isEmpty(tbBusinessAgentPos)) {
                businessAgentMap = tbBusinessAgentPos.stream().collect(Collectors.groupingBy(TbBusinessAgentPo::getGroupId));
            }

            for (BusinessGroupPageVo businessGroupPageVo : businessGroupPageVos) {
                int num = 0;
                int totalOrderCount = 0;
                BigDecimal totalSettleCommission = new BigDecimal(0);
                List<TbBusinessAgentPo> tbBusinessAgentPoList = businessAgentMap.get(businessGroupPageVo.getId());
                if (!CollectionUtils.isEmpty(tbBusinessAgentPoList)) {
                    // 分组成员数量
                    num = tbBusinessAgentPoList.size();
                    // 总订单数量
                    totalOrderCount = tbBusinessAgentPoList.stream()
                            .mapToInt(TbBusinessAgentPo::getTotalOrderCount)
                            .sum();
                    // 结算总佣金
                    totalSettleCommission = tbBusinessAgentPoList.stream()
                            .map(TbBusinessAgentPo::getTotalCommission)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                }
                businessGroupPageVo.setNum(num);
                businessGroupPageVo.setTotalOrderCount(totalOrderCount);
                businessGroupPageVo.setTotalSettleCommission(totalSettleCommission);
            }
        }

        PageInfo<BusinessGroupPageVo> pageInfo = new PageInfo<>(businessGroupPageVos);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    // 添加分组
    private Long createBusinessGroup(BusinessGroupSaveDto businessGroupSaveDto) {
        Long businessId = businessGroupSaveDto.getBusinessId();
        Long agentId = businessGroupSaveDto.getAgentId();
        String groupName = businessGroupSaveDto.getGroupName();
        List<Long> userIds = businessGroupSaveDto.getUserIds();
        BigDecimal commissionRate = businessGroupSaveDto.getCommissionRate();

        // 分组名称不能重复
        Integer count = baseMapper.selectCount(new QueryWrapper<TbBusinessGroupPo>()
                .eq("del_state", 0)
                .eq("business_id", businessId)
                .eq("agent_id", agentId)
                .eq("group_name", groupName));
        if (count != null && count > 0) {
            Throw.isBusinessException("分组名称不能重复");
        }

        // 新增
        LocalDateTime now = LocalDateTime.now();
        TbBusinessGroupPo tbBusinessGroupPo = new TbBusinessGroupPo();
        tbBusinessGroupPo.setBusinessId(businessId);
        tbBusinessGroupPo.setAgentId(agentId);
        tbBusinessGroupPo.setGroupName(groupName);
        tbBusinessGroupPo.setNum(0);
        tbBusinessGroupPo.setCommissionRate(commissionRate);
        tbBusinessGroupPo.setCreateTime(now);
        tbBusinessGroupPo.setUpdateTime(now);

        int insert = baseMapper.insert(tbBusinessGroupPo);
        if (insert == 0) {
            Throw.isBusinessException("保存分组失败");
        }

        Long groupId = tbBusinessGroupPo.getId();
        if (CollectionUtils.isEmpty(userIds)) {
            return groupId;
        }

        // 更新人员分组id，分组人员数量
        updateGroupUsers(groupId, businessId, agentId, userIds);

        return groupId;
    }

    private void updateGroupUsers(Long groupId, Long businessId, Long agentId, List<Long> userIds) {
        List<TbBusinessAgentPo> tbBusinessAgentPos = businessAgentMapper.selectList(new QueryWrapper<TbBusinessAgentPo>()
                .eq("del_state", 0)
                .eq("business_id", businessId)
                .eq("agent_id", agentId)
                .in("user_id", userIds));
        if (CollectionUtils.isEmpty(tbBusinessAgentPos)) {
            return;
        }

        List<Long> groupIds = new ArrayList<>();
        groupIds.add(groupId);

        LocalDateTime now = LocalDateTime.now();
        for (TbBusinessAgentPo tbBusinessAgentPo : tbBusinessAgentPos) {
            groupIds.add(tbBusinessAgentPo.getGroupId());
            // 更新分组id
            tbBusinessAgentPo.setGroupId(groupId);
            tbBusinessAgentPo.setUpdateTime(now);
            businessAgentMapper.updateById(tbBusinessAgentPo);
        }

        // 去重分组id
        groupIds = groupIds.stream().distinct().collect(Collectors.toList());
        // 更新分组人数
        for (Long gId : groupIds) {
            baseMapper.updateNum(gId);
        }
    }

    // 保存商家、经纪人分组信息
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Long saveBusinessGroup(BusinessGroupSaveDto businessGroupSaveDto) {
        Long id = businessGroupSaveDto.getId();
        String groupName = businessGroupSaveDto.getGroupName();
        BigDecimal commissionRate = businessGroupSaveDto.getCommissionRate();
        if (commissionRate == null) {
            commissionRate = BigDecimal.ZERO;
        }
        List<Long> userIds = businessGroupSaveDto.getUserIds();
        // 去重
        userIds = userIds.stream().distinct().collect(Collectors.toList());
        Long businessId = businessGroupSaveDto.getBusinessId();
        Long agentId = businessGroupSaveDto.getAgentId();
        businessGroupSaveDto.setUserIds(userIds);
        businessGroupSaveDto.setBusinessId(businessId);
        businessGroupSaveDto.setAgentId(agentId);

        if (StringUtils.isEmpty(groupName)) {
            Throw.isBusinessException("请填写分组名称");
        }

        if (commissionRate.compareTo(BigDecimal.ZERO) < 0 || commissionRate.compareTo(BigDecimal.valueOf(100)) > 0) {
            Throw.isBusinessException("请填写正确的分组佣金比例：0-100");
        }

        LocalDateTime now = LocalDateTime.now();

        if (id == null) {
            return createBusinessGroup(businessGroupSaveDto);
        }

        // 分组名称不能重复
        List<TbBusinessGroupPo> tbBusinessGroupPos = baseMapper.selectList(new QueryWrapper<TbBusinessGroupPo>()
                .eq("del_state", 0)
                .eq("business_id", businessId)
                .eq("agent_id", agentId)
                .eq("group_name", groupName));
        if (!CollectionUtils.isEmpty(tbBusinessGroupPos)) {
            if (tbBusinessGroupPos.size() > 1) {
                Throw.isBusinessException("分组名称不能重复");
            }

            if (!tbBusinessGroupPos.get(0).getId().equals(id)) {
                Throw.isBusinessException("分组名称不能重复");
            }
        }

        // 编辑
        TbBusinessGroupPo tbBusinessGroupPo = baseMapper.selectById(id);
        if (tbBusinessGroupPo == null) {
            Throw.isBusinessException("未找到分组数据");
        }
        if (!tbBusinessGroupPo.getBusinessId().equals(businessId) && !tbBusinessGroupPo.getAgentId().equals(agentId)) {
            Throw.isBusinessException("未找到分组数据");
        }

        tbBusinessGroupPo.setGroupName(groupName);
        tbBusinessGroupPo.setCommissionRate(commissionRate);
        tbBusinessGroupPo.setUpdateTime(now);
        int update = baseMapper.updateById(tbBusinessGroupPo);
        if (update == 0) {
            Throw.isBusinessException("保存分组失败");
        }

        // 更新人员分组id，分组人员数量
        if (!userIds.isEmpty()) {
            updateGroupUsers(id, businessId, agentId, userIds);
        }

        return id;
    }

    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Boolean deleteBusinessGroup(Long id, Long businessId, Long agentId) {
        TbBusinessGroupPo tbBusinessGroupPo = baseMapper.selectById(id);
        if (tbBusinessGroupPo == null || tbBusinessGroupPo.getDelState() != 0) {
            Throw.isBusinessException("未找到分组数据");
        }

        if (!tbBusinessGroupPo.getBusinessId().equals(businessId) && !tbBusinessGroupPo.getAgentId().equals(agentId)) {
            Throw.isBusinessException("未找到分组数据");
        }

        if (BusinessGroupDefaultStateEnum.YES.getValue().equals(tbBusinessGroupPo.getDefaultState())) {
            Throw.isBusinessException("不能删除默认分组");
        }

        // 查找该商家、经纪人的默认分组
        TbBusinessGroupPo businessGroupPo;
        businessGroupPo = getDefaultGroupWithInit(businessId, agentId);

        // 将删除的分组下的成员划分到未分组中
        List<TbBusinessAgentPo> businessAgentPos = businessAgentMapper.selectList(new QueryWrapper<TbBusinessAgentPo>()
                .eq("del_state", 0)
                .eq("group_id", id));
        if (!CollectionUtils.isEmpty(businessAgentPos)) {
            for (TbBusinessAgentPo businessAgentPo : businessAgentPos) {
                businessAgentPo.setGroupId(businessGroupPo.getId());
                businessAgentMapper.updateById(businessAgentPo);
            }
        }

        // 更新未分组人数
        baseMapper.updateNum(businessGroupPo.getId());

        // 删除分组
        tbBusinessGroupPo.setDelState(1);
        tbBusinessGroupPo.setUpdateTime(LocalDateTime.now());
        int update = baseMapper.updateById(tbBusinessGroupPo);
        if (update == 0) {
            Throw.isBusinessException("删除失败");
        }

        return true;
    }

    // 获取商家/经纪人默认分组，如果没有，初始化一个
    @Override
    public TbBusinessGroupPo getDefaultGroupWithInit(Long businessId, Long agentId) {
        if (businessId == null) {
            businessId = 0L;
        }
        if (agentId == null) {
            agentId = 0L;
        }
        TbBusinessGroupPo groupPo = baseMapper.getBusinessOrAgentDefaultGroup(businessId, agentId);
        if (groupPo != null) {
            return groupPo;
        }

        // 新增默认分组，分组名称=未分组
        LocalDateTime now = LocalDateTime.now();
        TbBusinessGroupPo tbBusinessGroupPo = new TbBusinessGroupPo();
        tbBusinessGroupPo.setBusinessId(businessId);
        tbBusinessGroupPo.setAgentId(agentId);
        tbBusinessGroupPo.setGroupName("未分组");
        tbBusinessGroupPo.setCommissionRate(BigDecimal.ZERO);
        tbBusinessGroupPo.setDefaultState(BusinessGroupDefaultStateEnum.YES.getValue());
        tbBusinessGroupPo.setNum(0);
        tbBusinessGroupPo.setCreateTime(now);
        tbBusinessGroupPo.setUpdateTime(now);
        int count = baseMapper.insert(tbBusinessGroupPo);
        if (count == 0) {
            log.error("新增默认分组失败");
            Throw.isBusinessException("新增默认分组失败");
        }

        return tbBusinessGroupPo;
    }
}
